Skip to content

Add project variable migration support#184

Open
premtsd-code wants to merge 3 commits into
add-api-key-migrationfrom
add-project-variable-migration
Open

Add project variable migration support#184
premtsd-code wants to merge 3 commits into
add-api-key-migrationfrom
add-project-variable-migration

Conversation

@premtsd-code
Copy link
Copy Markdown
Contributor

Summary

Stacks on #183. Adds project-variable as a migrable resource using the Appwrite SDK's Project::listVariables() (source) and a direct dbForProject->createDocument('variables', ...) (destination) that mirrors upstream Project::Variables::Create exactly.

Notes

  • Resource::TYPE_PROJECT_VARIABLE = 'project-variable' (kebab) — placed in GROUP_INTEGRATIONS_RESOURCES alongside platform/api-key for minimum changes to other Source/Destination implementations.
  • Destination writes resourceType: 'project' (singular, as upstream does for project-scope) with empty resourceInternalId/resourceId and a synthesized search field.
  • Secret variables: the SDK strips value on read for secret variables, so secrets will arrive with empty values. Operator re-enters them on the destination side. (Same caveat as API key secrets.)

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR adds project-variable as a migratable resource in the GROUP_SETTINGS group, stacking on the API key migration PR. The source reads variables via Project::listVariables() with cursor-based pagination, and the destination writes directly to the variables collection with resourceType: 'project', matching the upstream create behavior.

  • ProjectVariable resource class, exportGroupSettings/exportProjectVariables in the Appwrite source, and importSettingsResource/createProjectVariable in the destination are all wired up consistently with the existing platform/api-key pattern.
  • Transfer::GROUP_SETTINGS and GROUP_SETTINGS_RESOURCES are correctly defined, but the GROUP_SETTINGS arm is absent from extractServices(), causing it to throw for any caller that passes 'settings'.

Confidence Score: 4/5

The settings group is unusable via extractServices until the missing match arm is added; the rest of the migration wiring is sound.

The extractServices() match expression has no GROUP_SETTINGS arm, so any caller passing Transfer::GROUP_SETTINGS hits the default and throws. The remainder of the change is consistent with existing patterns.

src/Migration/Transfer.php — the extractServices() match expression needs the GROUP_SETTINGS arm before the settings group is fully operational.

Important Files Changed

Filename Overview
src/Migration/Transfer.php GROUP_SETTINGS constant and GROUP_SETTINGS_RESOURCES populated correctly, but the GROUP_SETTINGS arm is still absent from the extractServices() match expression, causing a thrown exception when callers pass Transfer::GROUP_SETTINGS to that method.
src/Migration/Destinations/Appwrite.php Adds importSettingsResource and createProjectVariable; duplicate-check and document write follow the same pattern as createApiKey/createPlatform, but createProjectVariable omits the purgeCachedDocument call that both peer methods include.
src/Migration/Sources/Appwrite.php Adds exportGroupSettings/exportProjectVariables following the same pagination and error-handling pattern as exportApiKeys; reportSettings correctly counts via listVariables.
src/Migration/Resources/Settings/ProjectVariable.php New resource class for project variables; correctly implements Resource interface with key/value/secret fields and proper serialization.
src/Migration/Source.php Adds GROUP_SETTINGS to the group→resources mapping and the export dispatch switch, plus the abstract exportGroupSettings method; consistent with the existing pattern.
src/Migration/Resource.php TYPE_PROJECT_VARIABLE constant added and inserted into ALL_RESOURCE_TYPES; placement and naming are consistent with other constants.
tests/Migration/Unit/Adapters/MockSource.php exportGroupSettings stub added; follows the same pattern as exportGroupBackups in MockSource.

Comments Outside Diff (1)

  1. src/Migration/Transfer.php, line 426-427 (link)

    P1 The extractServices() match expression handles every other group constant but is missing a GROUP_SETTINGS arm. Any caller that passes Transfer::GROUP_SETTINGS (or the string 'settings') to this method will hit the default arm and throw 'No service group found', making the new settings group completely unusable through this API.

Reviews (4): Last reviewed commit: "Remove unneeded comment in createProject..." | Re-trigger Greptile

Comment thread src/Migration/Destinations/Appwrite.php Outdated
Comment on lines 3217 to 3225
} catch (DuplicateException) {
$resource->setStatus(Resource::STATUS_SKIPPED, 'Project variable already exists');
return false;
}

return true;
}

private function validateFieldsForIndexes(Index $resource, UtopiaDocument $table, array &$lengths)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Both createPlatform and createApiKey call $this->dbForPlatform->purgeCachedDocument('projects', $this->project) after writing their documents. createProjectVariable omits this. If the platform's projects document caches any project-level metadata (variable counts, etc.), created variables won't be reflected until the cache naturally expires. Worth verifying against the upstream Project::Variables::Create implementation to confirm whether the purge is needed here too.

Suggested change
} catch (DuplicateException) {
$resource->setStatus(Resource::STATUS_SKIPPED, 'Project variable already exists');
return false;
}
return true;
}
private function validateFieldsForIndexes(Index $resource, UtopiaDocument $table, array &$lengths)
} catch (DuplicateException) {
$resource->setStatus(Resource::STATUS_SKIPPED, 'Project variable already exists');
return false;
}
$this->dbForPlatform->purgeCachedDocument('projects', $this->project);
return true;
}
private function validateFieldsForIndexes(Index $resource, UtopiaDocument $table, array &$lengths)

Introduces Transfer::GROUP_SETTINGS for project-level configuration
resources that aren't external integrations. Project variables are
the first inhabitant; webhooks will follow in a stacked PR.

- New abstract Source::exportGroupSettings() with no-op stubs in
  CSV/JSON/Firebase/NHost sources.
- Appwrite source: project variables exported via Project SDK
  listVariables() with cursor pagination.
- Appwrite destination: createProjectVariable writes directly to
  dbForProject 'variables' collection, mirroring upstream Project
  Variables Create payload (resourceType 'project', empty resource id).
@premtsd-code premtsd-code force-pushed the add-project-variable-migration branch from c040472 to 3376bed Compare May 14, 2026 19:00
- MockSource now stubs exportGroupSettings so the class is concrete
  (clears PHPUnit fatal + PHPStan level-3 error).
- Pint ordered_imports auto-fix on Sources/Appwrite.php and
  Destinations/Appwrite.php.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant